--- title: ImageFilter Data Augmentation keywords: fastai sidebar: home_sidebar summary: "Apply `PIL.ImageFilter`s to your input images" description: "Apply `PIL.ImageFilter`s to your input images" nb_path: "nbs/augment_albumentations.ipynb" ---
{% raw %}
{% endraw %} {% raw %}
%load_ext autoreload
%autoreload 2

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'
{% endraw %} {% raw %}
{% endraw %} {% raw %}
{% endraw %} {% raw %}
files = get_image_files('../assets/imgs')
f1    = files[0]
f2    = files[1]
img1  = PIL.Image.open(f1).resize((500,300))
img2  = PIL.Image.open(f2).resize((500,300))
{% endraw %} {% raw %}
img1
img2
{% endraw %} {% raw %}
to_img  = lambda x:   PILImage.create(x)
as_arr  = lambda x:   np.array(x)
aug     = lambda op,img: op(image=as_arr(img))['image']
aug_img = lambda op,img: to_img(aug(op,img))
side_by_side = lambda arr1,arr2: np.hstack((arr1,arr2))
compare = lambda op,img: PIL.Image.fromarray(side_by_side(img, aug(op,img)))

def compose_augs(augs:list, img:PIL.Image.Image):
    if not isinstance(augs, list): augs=[augs]
    for aug in augs:
        img = aug_img(aug,img)
    return img
{% endraw %}

Blurring Transforms

One Of

  • Blur
  • MotionBlur
{% raw %}
blur = Blur(always_apply=True)

compare(blur, img2)
{% endraw %} {% raw %}
motion_blur = MotionBlur(blur_limit=(15,15), always_apply=True)
compare(motion_blur, img1)
{% endraw %}

Style Transfer-Esque

  • MedianBlur
  • IAAAEmboss
{% raw %}
median_blur = MedianBlur(blur_limit=(3,7), always_apply=True)
compare(median_blur, img1)
{% endraw %} {% raw %}
emboss = IAAEmboss(strength=(0.2,0.99), always_apply=True)
compare(emboss, img1)
{% endraw %}

Other

  • FancyPCA
{% raw %}
pca = FancyPCA(0.3, always_apply=True)
compare(pca, img2)
{% endraw %}

Color Tones

  • Solarize
  • ToGray
  • Sepia
{% raw %}
solarize = A.Solarize(always_apply=True)
compare(solarize, img2)
{% endraw %} {% raw %}
gray = ToGray(always_apply=True)
compare(gray, img2)
{% endraw %} {% raw %}
sepia = ToSepia(always_apply=True)
compare(sepia, img2)
{% endraw %}

Noise

One of:

  • IAAAAdditiveGaussianNoise
  • GaussNoise

  • JpegCompress

{% raw %}
tfm = IAAAdditiveGaussianNoise(always_apply=True)
compare(tfm, img2)
{% endraw %} {% raw %}
gauss_noise = GaussNoise(always_apply=True)
compare(gauss_noise, img2)
{% endraw %} {% raw %}
jpeg_compress = JpegCompression(quality_lower=25, quality_upper=55, always_apply=True)
compare(jpeg_compress, img2)
{% endraw %} {% raw %}
posterize = Posterize(True)
compare(posterize, img1)
{% endraw %}

Weather Transforms

  • Sun Flare
{% raw %}
rain = A.RandomRain(always_apply=True, blur_value=3)
compare(rain, img2)
{% endraw %} {% raw %}
snow = A.RandomSnow(always_apply=True)
compare(snow, img2)
{% endraw %} {% raw %}
fog = A.RandomFog(always_apply=True)
compare(fog, img1)
{% endraw %} {% raw %}
sun_flare = RandomSunFlare(always_apply=True, src_radius=80)
compare(sun_flare, img2.resize((224,224)))
{% endraw %}

Lighting Transforms

  • RandomContrast
  • RandomBrightness
  • CLAHE
{% raw %}
random_contrast = RandomContrast(always_apply=True)
compare(random_contrast, img1)
{% endraw %} {% raw %}
random_brightness = RandomBrightness(0.05, always_apply=True)
compare(random_brightness, img1)
{% endraw %} {% raw %}
clahe = CLAHE(always_apply=True)
compare(clahe, img2)
{% endraw %}

Channel Level Transforms

  • ChannelShuffle
  • HueSaturationValue
  • RGBShift
{% raw %}
channel_shuffle = ChannelShuffle(always_apply=True)
compare(channel_shuffle,img2)
{% endraw %} {% raw %}
hsv = HueSaturationValue(val_shift_limit=10)
compare(hsv, img1)
{% endraw %} {% raw %}
rgb_shift = RGBShift(always_apply=True)
compare(rgb_shift, img2)
{% endraw %}

Merging With FastAI

{% raw %}

albu_augment[source]

albu_augment(aug, img)

{% endraw %} {% raw %}

class AlbumentationsWrapper[source]

AlbumentationsWrapper(aug) :: Transform

Wrapper function for any Albumentations Transform
{% endraw %} {% raw %}
{% endraw %}

Formulate Different Transform Blocks

The transforms below are segregated into 8 different blocks:

  • Blurring
  • Style
  • Weather
  • Noise
  • ColorTones
  • ColorChannel
  • Lighting
  • Other

HueSaturationValue has a low val_shift_limit to minimise lighting change, as that will come from other lighting transforms

{% raw %}
{% endraw %} {% raw %}
{% endraw %} {% raw %}
albu_tfms = AlbumentationsWrapper(Tfms)
{% endraw %} {% raw %}
hstack([albu_tfms(f2), albu_tfms(f2), albu_tfms(f2)])
hstack([albu_tfms(f2), albu_tfms(f2), albu_tfms(f2)])
hstack([albu_tfms(f2), albu_tfms(f2), albu_tfms(f2)])
{% endraw %} {% raw %}
f2 = f1
hstack([albu_tfms(f2), albu_tfms(f2), albu_tfms(f2)])
hstack([albu_tfms(f2), albu_tfms(f2), albu_tfms(f2)])
hstack([albu_tfms(f2), albu_tfms(f2), albu_tfms(f2)])
{% endraw %} {% raw %}
dblock = DataBlock(
    blocks     = (ImageBlock, CategoryBlock),
    get_items  = get_image_files,
    get_x      = Pipeline([PILImage.create, albu_tfms]),
    get_y      = parent_label,
    splitter   = RandomSplitter(seed=42, valid_pct=0.),
    item_tfms  = [Resize(size=224, method=ResizeMethod.Squish, pad_mode=PadMode.Zeros)],
    batch_tfms = [Normalize.from_stats(*imagenet_stats)]
)
{% endraw %} {% raw %}
dls = dblock.dataloaders('../assets/imgs', bs=3)
{% endraw %} {% raw %}
dls.show_batch(unique=True)
{% endraw %}

Export

{% raw %}
from nbdev.export import notebook2script
{% endraw %} {% raw %}
notebook2script('06_augment_albumentations.ipynb')
Converted 06_augment_albumentations.ipynb.
{% endraw %}